{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lesson 18 - Interactive Visualization with Bokeh\n",
    "\n",
    "### Readings\n",
    "\n",
    "* [Bokeh User Guide](http://bokeh.pydata.org/en/latest/docs/user_guide.html)\n",
    "\n",
    "### Table of Contents\n",
    "\n",
    "* [Getting started](#intro)\n",
    "* [About the HTML file](#html)\n",
    "* [Tools](#tools)\n",
    "* [Time-series graphs](#time)\n",
    "* [Vectorized colors and sizes](#vectorized)\n",
    "* [Linked panning and brushing](#linked)\n",
    "* [Interact example](#interact)\n",
    "* [Addendum: Pandas Panels](#panels)\n",
    "\n",
    "From the Bokeh [homepage](http://bokeh.pydata.org/en/latest/):\n",
    "\n",
    "Bokeh is a Python interactive visualization library that targets modern web browsers for presentation. Its goal is to provide elegant, concise construction of novel graphics in the style of D3.js, and to extend this capability with high-performance interactivity over very large or streaming datasets. Bokeh can help anyone who would like to quickly and easily create interactive plots, dashboards, and data applications.\n",
    "\n",
    "To get started using Bokeh to make your visualizations, see the [User Guide](http://bokeh.pydata.org/en/latest/docs/user_guide.html).\n",
    "\n",
    "A complete API reference of Bokeh is at [Reference Guide](http://bokeh.pydata.org/en/latest/docs/reference.html).\n",
    "\n",
    "To see examples of how you might use Bokeh with your own data, check out the [Gallery](http://bokeh.pydata.org/en/latest/docs/gallery.html) and the [Notebook Viewer Gallery](http://nbviewer.jupyter.org/github/bokeh/bokeh-notebooks/blob/master/index.ipynb)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"intro\"></a>\n",
    "\n",
    "### Getting started\n",
    "\n",
    "#### Installation\n",
    "\n",
    "First make sure you have `bokeh` installed. We will also use `pandas-datareader` to download stock quote data.\n",
    "\n",
    "```\n",
    "conda install bokeh\n",
    "pip install pandas-datareader\n",
    "```\n",
    "\n",
    "#### Two interface levels for Bokeh\n",
    "\n",
    "1. `bokeh.models` -- a low-level interface that provides the most flexibility to application developers\n",
    "2. `bokeh.plotting` -- a higher-level interface centered around composing visual glyphs\n",
    "\n",
    "We'll use only the `bokeh.plotting` interface today."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Example: bokeh.plotting interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the figure object, within which we create \"glyphs\":"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure, output_file, show"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a figure object, then create some glyphs, then customize it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = figure(plot_width=500, plot_height=400) # can also leave figure() empty\n",
    "\n",
    "p.circle([0, 1, 2, 3, 4], [112, 7, 73, 6, 2], size=12, color='red')\n",
    "p.triangle([0, 1, 2, 3, 4], [100, 12, 68, 15, 10], size=[5, 10, 15, 20, 25], \n",
    "           color='blue', alpha=0.5)\n",
    "\n",
    "p.title.text = 'plotting example'\n",
    "p.title.text_color = 'orange'\n",
    "\n",
    "p.xaxis.axis_label = 'X-axis label'\n",
    "p.yaxis.axis_label = 'Y-axis label'\n",
    "\n",
    "p.xaxis.minor_tick_line_color = 'red'\n",
    "p.yaxis.minor_tick_line_color = None\n",
    "\n",
    "output_file('scatter_plotting.html', mode='cdn') # cdn = content delivery network\n",
    "\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a new plot with more glyphs and elements:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# prepare some data\n",
    "x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]\n",
    "y0 = [i**2 for i in x]\n",
    "y1 = [10**i for i in x]\n",
    "y2 = [10**(i**2) for i in x]\n",
    "\n",
    "# output to static HTML file\n",
    "output_file(\"log_lines.html\")\n",
    "\n",
    "# NEW: create a plot with tools and other parameters set in the figure\n",
    "p = figure(\n",
    "   tools=\"pan,box_zoom,reset,save\",\n",
    "   y_axis_type=\"log\", y_range=[0.001, 10**11], title=\"log axis example\",\n",
    "   x_axis_label='sections', y_axis_label='particles'\n",
    ")\n",
    "\n",
    "# add some renderers\n",
    "p.line(x, x, legend=\"y=x\")\n",
    "p.circle(x, x, legend=\"y=x\", fill_color=\"white\", size=8)\n",
    "p.line(x, y0, legend=\"y=x^2\", line_width=3)\n",
    "p.line(x, y1, legend=\"y=10^x\", line_color=\"red\")\n",
    "p.circle(x, y1, legend=\"y=10^x\", fill_color=\"red\", line_color=\"red\", size=6)\n",
    "p.line(x, y2, legend=\"y=10^x^2\", line_color=\"orange\", line_dash=\"4 4\")\n",
    "\n",
    "# show the results\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"html\"></a>\n",
    "\n",
    "### About the HTML file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Open up the HTML source code in a text editor.\n",
    "\n",
    "The HTML file is composed of HTML tags and code. The code is composed of Javascript and CSS. Javascript is the scripting language that makes possible interaction between the elements in the browser. CSS controls the styling of text and everything else.\n",
    "\n",
    "The style sheet is stored in a remote server. Every time you generate a graph, Bokeh is pulling the CSS and Javascript files from a server (pydata.org). This is the default mode, called CDN (content delivery network). There are several options for where to host these files:\n",
    "\n",
    "* `mode=cdn` -- online (default)\n",
    "* `mode=relative` -- locally with relative path\n",
    "* `mode=absolute` -- locally with absolute path\n",
    "* `mode=inline` -- locally in the HTML file (stand-alone option)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"tools\"></a>\n",
    "\n",
    "### Tools"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Customization: `tools`, `toolbar_location`.\n",
    "* Lots more about tools [here](http://bokeh.pydata.org/en/latest/docs/user_guide/tools.html).\n",
    "* By the way, another useful glyph is `line`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = figure(plot_width=500, plot_height=400,\n",
    "           tools='pan,wheel_zoom,box_zoom,lasso_select,reset,save',\n",
    "           toolbar_location='below', toolbar_sticky=False) \n",
    "\n",
    "p.circle([0, 1, 2, 3, 4], [112, 7, 73, 6, 2], size=12, color='red')\n",
    "p.line([0, 1, 2, 3, 4], [112, 7, 73, 6, 2], line_width=2, color='blue')\n",
    "\n",
    "output_file('scatter_tools.html', mode='inline')\n",
    "\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"time\"></a>\n",
    "\n",
    "### Time-series graphs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Stock data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas_datareader as pdr\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "start = pd.datetime(2014, 1, 1)\n",
    "end = pd.datetime.today()\n",
    "aapl = pdr.data.DataReader('AAPL', 'iex', start, end)\n",
    "aapl.set_index(pd.to_datetime(aapl.index), inplace=True)\n",
    "# if this fails, check https://pydata.github.io/pandas-datareader/stable/remote_data.html for alternate sources"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>volume</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-01-02</th>\n",
       "      <td>72.8554</td>\n",
       "      <td>73.0324</td>\n",
       "      <td>72.3757</td>\n",
       "      <td>72.5211</td>\n",
       "      <td>58791957</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-03</th>\n",
       "      <td>72.4857</td>\n",
       "      <td>72.5958</td>\n",
       "      <td>70.8560</td>\n",
       "      <td>70.9281</td>\n",
       "      <td>98303870</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-06</th>\n",
       "      <td>70.4653</td>\n",
       "      <td>71.6912</td>\n",
       "      <td>69.9605</td>\n",
       "      <td>71.3149</td>\n",
       "      <td>103359151</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-07</th>\n",
       "      <td>71.3660</td>\n",
       "      <td>71.5811</td>\n",
       "      <td>70.5276</td>\n",
       "      <td>70.8046</td>\n",
       "      <td>79432766</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-08</th>\n",
       "      <td>70.6436</td>\n",
       "      <td>71.5286</td>\n",
       "      <td>70.6279</td>\n",
       "      <td>71.2533</td>\n",
       "      <td>64686685</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               open     high      low    close     volume\n",
       "date                                                     \n",
       "2014-01-02  72.8554  73.0324  72.3757  72.5211   58791957\n",
       "2014-01-03  72.4857  72.5958  70.8560  70.9281   98303870\n",
       "2014-01-06  70.4653  71.6912  69.9605  71.3149  103359151\n",
       "2014-01-07  71.3660  71.5811  70.5276  70.8046   79432766\n",
       "2014-01-08  70.6436  71.5286  70.6279  71.2533   64686685"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "aapl.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>volume</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2018-11-20</th>\n",
       "      <td>178.37</td>\n",
       "      <td>181.470</td>\n",
       "      <td>175.51</td>\n",
       "      <td>176.98</td>\n",
       "      <td>67825247</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11-21</th>\n",
       "      <td>179.73</td>\n",
       "      <td>180.270</td>\n",
       "      <td>176.55</td>\n",
       "      <td>176.78</td>\n",
       "      <td>31124210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11-23</th>\n",
       "      <td>174.94</td>\n",
       "      <td>176.595</td>\n",
       "      <td>172.10</td>\n",
       "      <td>172.29</td>\n",
       "      <td>23623972</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11-26</th>\n",
       "      <td>174.24</td>\n",
       "      <td>174.950</td>\n",
       "      <td>170.26</td>\n",
       "      <td>174.62</td>\n",
       "      <td>44998520</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11-27</th>\n",
       "      <td>171.51</td>\n",
       "      <td>174.770</td>\n",
       "      <td>170.88</td>\n",
       "      <td>174.24</td>\n",
       "      <td>41387377</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              open     high     low   close    volume\n",
       "date                                                 \n",
       "2018-11-20  178.37  181.470  175.51  176.98  67825247\n",
       "2018-11-21  179.73  180.270  176.55  176.78  31124210\n",
       "2018-11-23  174.94  176.595  172.10  172.29  23623972\n",
       "2018-11-26  174.24  174.950  170.26  174.62  44998520\n",
       "2018-11-27  171.51  174.770  170.88  174.24  41387377"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "aapl.tail()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The key part of a time-series graph is: ` x_axis_type='datetime'`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = figure(width=1000, height=500, x_axis_type='datetime')\n",
    "\n",
    "p.line(aapl.index, aapl.close, color='maroon', alpha=0.5)\n",
    "\n",
    "p.xaxis.axis_label = 'Date'\n",
    "p.yaxis.axis_label = 'Price'\n",
    "\n",
    "p.ygrid.band_fill_color=\"olive\"\n",
    "p.ygrid.band_fill_alpha = 0.1\n",
    "\n",
    "output_file('timeseries.html')\n",
    "\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Precipitation data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>DATE</th>\n",
       "      <th>LATITUDE</th>\n",
       "      <th>LONGITUDE</th>\n",
       "      <th>ELEVATION</th>\n",
       "      <th>PRCP</th>\n",
       "      <th>MONTH</th>\n",
       "      <th>YEAR</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2008-12-01</td>\n",
       "      <td>32.82540</td>\n",
       "      <td>-117.2397</td>\n",
       "      <td>154.80</td>\n",
       "      <td>112.40</td>\n",
       "      <td>12</td>\n",
       "      <td>2008</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2009-01-01</td>\n",
       "      <td>32.82540</td>\n",
       "      <td>-117.2397</td>\n",
       "      <td>154.80</td>\n",
       "      <td>6.90</td>\n",
       "      <td>1</td>\n",
       "      <td>2009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2009-02-01</td>\n",
       "      <td>32.82540</td>\n",
       "      <td>-117.2397</td>\n",
       "      <td>154.80</td>\n",
       "      <td>72.60</td>\n",
       "      <td>2</td>\n",
       "      <td>2009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2009-03-01</td>\n",
       "      <td>32.82555</td>\n",
       "      <td>-117.2449</td>\n",
       "      <td>152.25</td>\n",
       "      <td>6.10</td>\n",
       "      <td>3</td>\n",
       "      <td>2009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2009-04-01</td>\n",
       "      <td>32.82555</td>\n",
       "      <td>-117.2449</td>\n",
       "      <td>152.25</td>\n",
       "      <td>2.05</td>\n",
       "      <td>4</td>\n",
       "      <td>2009</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        DATE  LATITUDE  LONGITUDE  ELEVATION    PRCP  MONTH  YEAR\n",
       "0 2008-12-01  32.82540  -117.2397     154.80  112.40     12  2008\n",
       "1 2009-01-01  32.82540  -117.2397     154.80    6.90      1  2009\n",
       "2 2009-02-01  32.82540  -117.2397     154.80   72.60      2  2009\n",
       "3 2009-03-01  32.82555  -117.2449     152.25    6.10      3  2009\n",
       "4 2009-04-01  32.82555  -117.2449     152.25    2.05      4  2009"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# format the data: covert to datetime, average precipitation per month, get month and year, reset index\n",
    "df = pd.read_csv('../data/la_jolla_precip_monthly.csv')\n",
    "df['DATE'] = pd.to_datetime(df['DATE'])\n",
    "df = df.groupby('DATE').mean()\n",
    "df['MONTH'] = [x.month for x in df.index]\n",
    "df['YEAR'] = [x.year for x in df.index]\n",
    "df.reset_index(inplace=True)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = figure(width=1000, height=500, x_axis_type='datetime', \n",
    "           tools='pan,wheel_zoom,box_zoom,lasso_select,hover,reset,save')\n",
    "\n",
    "p.circle(df.DATE, df.PRCP, color='blue', size=10, alpha=0.5)\n",
    "p.line(df.DATE, df.PRCP, color='blue')\n",
    "\n",
    "output_file('precip.html')\n",
    "\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"vectorized\"></a>\n",
    "\n",
    "### Vectorized colors and sizes\n",
    "\n",
    "This example shows how it is possible to provide sequences of data values for glyph attributes like `fill_color` and `radius`. Other things to look out for in this example:\n",
    "\n",
    "* supplying an explicit list of tool names to `figure()`\n",
    "* fetching BokehJS resources from CDN using the mode argument\n",
    "* setting the `x_range` and `y_range` explicitly\n",
    "* turning a line off (by setting its value to `None`)\n",
    "* using NumPy arrays for supplying data\n",
    "* supplying a list of tools ([documentation](http://bokeh.pydata.org/en/latest/docs/user_guide/tools.html#configuring-plot-tools))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# prepare some data\n",
    "N = 4000\n",
    "x = np.random.random(size=N) * 100\n",
    "y = np.random.random(size=N) * 100\n",
    "radii = np.random.random(size=N) * 1.5\n",
    "colors = [\n",
    "    \"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)\n",
    "]\n",
    "\n",
    "# output to static HTML file (with CDN resources)\n",
    "output_file(\"color_scatter.html\", title=\"color scatter example\", mode=\"cdn\")\n",
    "\n",
    "TOOLS = 'box_select, box_zoom, lasso_select, pan, poly_select, tap, wheel_zoom, undo, redo, reset, save, zoom_in, zoom_out, crosshair, hover'\n",
    "\n",
    "# create a new plot with the tools above, and explicit ranges\n",
    "p = figure(tools=TOOLS, x_range=(0,100), y_range=(0,100))\n",
    "\n",
    "# add a circle renderer with vectorized colors and sizes\n",
    "p.circle(x,y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)\n",
    "\n",
    "# show the results\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"linked\"></a>\n",
    "\n",
    "### Linked panning and brushing\n",
    "\n",
    "Linking together various aspects of different plots can be a useful technique for data visualization. In Bokeh, such linkages are typically accomplished by sharing some plot component between plots. Below is an example that demonstrates **linked panning** (where changing the range of one plot causes others to update) by sharing range objects between the plots. Some other things to look out for in this example:\n",
    "\n",
    "* calling `figure()` multiple times to create multiple plots\n",
    "* using `gridplot()` to arrange several plots in an array\n",
    "* showing different glyphs glyph methods `Figure.triangle` and `Figure.square`\n",
    "* hiding the toolbar by setting `toolbar_location` to `None`\n",
    "* setting convenience arguments `color` (sets both `line_color` and `fill_color`) and `alpha` (sets both `line_alpha` and `fill_alpha`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.layouts import gridplot\n",
    "from bokeh.plotting import figure, output_file, show\n",
    "\n",
    "# prepare some data\n",
    "N = 100\n",
    "x = np.linspace(0, 4*np.pi, N)\n",
    "y0 = np.sin(x)\n",
    "y1 = np.cos(x)\n",
    "y2 = np.sin(x) + np.cos(x)\n",
    "\n",
    "# output to static HTML file\n",
    "output_file(\"linked_panning.html\")\n",
    "\n",
    "# create a new plot\n",
    "s1 = figure(width=250, plot_height=250, title=None)\n",
    "s1.circle(x, y0, size=10, color=\"navy\", alpha=0.5)\n",
    "\n",
    "# NEW: create a new plot and share both ranges\n",
    "s2 = figure(width=250, height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)\n",
    "s2.triangle(x, y1, size=10, color=\"firebrick\", alpha=0.5)\n",
    "\n",
    "# NEW: create a new plot and share only one range\n",
    "s3 = figure(width=250, height=250, x_range=s1.x_range, title=None)\n",
    "s3.square(x, y2, size=10, color=\"olive\", alpha=0.5)\n",
    "\n",
    "# NEW: put the subplots in a gridplot\n",
    "p = gridplot([[s1, s2, s3]], toolbar_location=None)\n",
    "\n",
    "# show the results\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although the toolbar is hidden, the pan tool is still present and active. Click and drag the above plots to pan them, and see how their ranges are linked together.\n",
    "\n",
    "Another linkage that is often useful is **linked brushing** (where a selection on one plot causes a selection to update on other plots). Below is an example that demonstrates linked brushing by sharing a ColumnDataSource between two plots:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import *\n",
    "from bokeh.models import ColumnDataSource\n",
    "\n",
    "# prepare some date\n",
    "N = 300\n",
    "x = np.linspace(0, 4*np.pi, N)\n",
    "y0 = np.sin(x)\n",
    "y1 = np.cos(x)\n",
    "\n",
    "# output to static HTML file\n",
    "output_file(\"linked_brushing.html\")\n",
    "\n",
    "# NEW: create a column data source for the plots to share\n",
    "source = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))\n",
    "\n",
    "TOOLS = \"pan,wheel_zoom,box_zoom,reset,save,box_select,lasso_select,hover\"\n",
    "\n",
    "# create a new plot and add a renderer\n",
    "left = figure(tools=TOOLS, width=350, height=350, title=None)\n",
    "left.circle('x', 'y0', source=source)\n",
    "\n",
    "# create another new plot and add a renderer\n",
    "right = figure(tools=TOOLS, width=350, height=350, title=None)\n",
    "right.circle('x', 'y1', source=source)\n",
    "\n",
    "# put the subplots in a gridplot\n",
    "p = gridplot([[left, right]])\n",
    "\n",
    "# show the results\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"interact\"></a>\n",
    "\n",
    "### Interact example\n",
    "\n",
    "This demo shows off an interactive visualization using Bokeh for plotting, and Jupyter interactors for widgets. The demo runs entirely inside the Jupyter notebook, with no Bokeh server required.\n",
    "\n",
    "The dropdown offers a choice of trigonometry functions to plot, and the sliders control the frequency, amplitude, and phase."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div class=\"bk-root\">\n",
       "        <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
       "        <span id=\"2776\">Loading BokehJS ...</span>\n",
       "    </div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "\n",
       "(function(root) {\n",
       "  function now() {\n",
       "    return new Date();\n",
       "  }\n",
       "\n",
       "  var force = true;\n",
       "\n",
       "  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n",
       "    root._bokeh_onload_callbacks = [];\n",
       "    root._bokeh_is_loading = undefined;\n",
       "  }\n",
       "\n",
       "  var JS_MIME_TYPE = 'application/javascript';\n",
       "  var HTML_MIME_TYPE = 'text/html';\n",
       "  var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
       "  var CLASS_NAME = 'output_bokeh rendered_html';\n",
       "\n",
       "  /**\n",
       "   * Render data to the DOM node\n",
       "   */\n",
       "  function render(props, node) {\n",
       "    var script = document.createElement(\"script\");\n",
       "    node.appendChild(script);\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when an output is cleared or removed\n",
       "   */\n",
       "  function handleClearOutput(event, handle) {\n",
       "    var cell = handle.cell;\n",
       "\n",
       "    var id = cell.output_area._bokeh_element_id;\n",
       "    var server_id = cell.output_area._bokeh_server_id;\n",
       "    // Clean up Bokeh references\n",
       "    if (id != null && id in Bokeh.index) {\n",
       "      Bokeh.index[id].model.document.clear();\n",
       "      delete Bokeh.index[id];\n",
       "    }\n",
       "\n",
       "    if (server_id !== undefined) {\n",
       "      // Clean up Bokeh references\n",
       "      var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
       "      cell.notebook.kernel.execute(cmd, {\n",
       "        iopub: {\n",
       "          output: function(msg) {\n",
       "            var id = msg.content.text.trim();\n",
       "            if (id in Bokeh.index) {\n",
       "              Bokeh.index[id].model.document.clear();\n",
       "              delete Bokeh.index[id];\n",
       "            }\n",
       "          }\n",
       "        }\n",
       "      });\n",
       "      // Destroy server and session\n",
       "      var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
       "      cell.notebook.kernel.execute(cmd);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when a new output is added\n",
       "   */\n",
       "  function handleAddOutput(event, handle) {\n",
       "    var output_area = handle.output_area;\n",
       "    var output = handle.output;\n",
       "\n",
       "    // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
       "    if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
       "      return\n",
       "    }\n",
       "\n",
       "    var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
       "\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
       "      toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
       "      // store reference to embed id on output_area\n",
       "      output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
       "    }\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
       "      var bk_div = document.createElement(\"div\");\n",
       "      bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
       "      var script_attrs = bk_div.children[0].attributes;\n",
       "      for (var i = 0; i < script_attrs.length; i++) {\n",
       "        toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
       "      }\n",
       "      // store reference to server id on output_area\n",
       "      output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
       "    }\n",
       "  }\n",
       "\n",
       "  function register_renderer(events, OutputArea) {\n",
       "\n",
       "    function append_mime(data, metadata, element) {\n",
       "      // create a DOM node to render to\n",
       "      var toinsert = this.create_output_subarea(\n",
       "        metadata,\n",
       "        CLASS_NAME,\n",
       "        EXEC_MIME_TYPE\n",
       "      );\n",
       "      this.keyboard_manager.register_events(toinsert);\n",
       "      // Render to node\n",
       "      var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
       "      render(props, toinsert[toinsert.length - 1]);\n",
       "      element.append(toinsert);\n",
       "      return toinsert\n",
       "    }\n",
       "\n",
       "    /* Handle when an output is cleared or removed */\n",
       "    events.on('clear_output.CodeCell', handleClearOutput);\n",
       "    events.on('delete.Cell', handleClearOutput);\n",
       "\n",
       "    /* Handle when a new output is added */\n",
       "    events.on('output_added.OutputArea', handleAddOutput);\n",
       "\n",
       "    /**\n",
       "     * Register the mime type and append_mime function with output_area\n",
       "     */\n",
       "    OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
       "      /* Is output safe? */\n",
       "      safe: true,\n",
       "      /* Index of renderer in `output_area.display_order` */\n",
       "      index: 0\n",
       "    });\n",
       "  }\n",
       "\n",
       "  // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
       "  if (root.Jupyter !== undefined) {\n",
       "    var events = require('base/js/events');\n",
       "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
       "\n",
       "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
       "      register_renderer(events, OutputArea);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  \n",
       "  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
       "    root._bokeh_timeout = Date.now() + 5000;\n",
       "    root._bokeh_failed_load = false;\n",
       "  }\n",
       "\n",
       "  var NB_LOAD_WARNING = {'data': {'text/html':\n",
       "     \"<div style='background-color: #fdd'>\\n\"+\n",
       "     \"<p>\\n\"+\n",
       "     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
       "     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
       "     \"</p>\\n\"+\n",
       "     \"<ul>\\n\"+\n",
       "     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
       "     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
       "     \"</ul>\\n\"+\n",
       "     \"<code>\\n\"+\n",
       "     \"from bokeh.resources import INLINE\\n\"+\n",
       "     \"output_notebook(resources=INLINE)\\n\"+\n",
       "     \"</code>\\n\"+\n",
       "     \"</div>\"}};\n",
       "\n",
       "  function display_loaded() {\n",
       "    var el = document.getElementById(\"2776\");\n",
       "    if (el != null) {\n",
       "      el.textContent = \"BokehJS is loading...\";\n",
       "    }\n",
       "    if (root.Bokeh !== undefined) {\n",
       "      if (el != null) {\n",
       "        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
       "      }\n",
       "    } else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(display_loaded, 100)\n",
       "    }\n",
       "  }\n",
       "\n",
       "\n",
       "  function run_callbacks() {\n",
       "    try {\n",
       "      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
       "    }\n",
       "    finally {\n",
       "      delete root._bokeh_onload_callbacks\n",
       "    }\n",
       "    console.info(\"Bokeh: all callbacks have finished\");\n",
       "  }\n",
       "\n",
       "  function load_libs(js_urls, callback) {\n",
       "    root._bokeh_onload_callbacks.push(callback);\n",
       "    if (root._bokeh_is_loading > 0) {\n",
       "      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
       "      return null;\n",
       "    }\n",
       "    if (js_urls == null || js_urls.length === 0) {\n",
       "      run_callbacks();\n",
       "      return null;\n",
       "    }\n",
       "    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
       "    root._bokeh_is_loading = js_urls.length;\n",
       "    for (var i = 0; i < js_urls.length; i++) {\n",
       "      var url = js_urls[i];\n",
       "      var s = document.createElement('script');\n",
       "      s.src = url;\n",
       "      s.async = false;\n",
       "      s.onreadystatechange = s.onload = function() {\n",
       "        root._bokeh_is_loading--;\n",
       "        if (root._bokeh_is_loading === 0) {\n",
       "          console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
       "          run_callbacks()\n",
       "        }\n",
       "      };\n",
       "      s.onerror = function() {\n",
       "        console.warn(\"failed to load library \" + url);\n",
       "      };\n",
       "      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
       "      document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "    }\n",
       "  };var element = document.getElementById(\"2776\");\n",
       "  if (element == null) {\n",
       "    console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2776' but no matching script tag was found. \")\n",
       "    return false;\n",
       "  }\n",
       "\n",
       "  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.1.min.js\"];\n",
       "\n",
       "  var inline_js = [\n",
       "    function(Bokeh) {\n",
       "      Bokeh.set_log_level(\"info\");\n",
       "    },\n",
       "    \n",
       "    function(Bokeh) {\n",
       "      \n",
       "    },\n",
       "    function(Bokeh) {\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.css\");\n",
       "    }\n",
       "  ];\n",
       "\n",
       "  function run_inline_js() {\n",
       "    \n",
       "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
       "      for (var i = 0; i < inline_js.length; i++) {\n",
       "        inline_js[i].call(root, root.Bokeh);\n",
       "      }if (force === true) {\n",
       "        display_loaded();\n",
       "      }} else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(run_inline_js, 100);\n",
       "    } else if (!root._bokeh_failed_load) {\n",
       "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
       "      root._bokeh_failed_load = true;\n",
       "    } else if (force !== true) {\n",
       "      var cell = $(document.getElementById(\"2776\")).parents('.cell').data().cell;\n",
       "      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
       "    }\n",
       "\n",
       "  }\n",
       "\n",
       "  if (root._bokeh_is_loading === 0) {\n",
       "    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
       "    run_inline_js();\n",
       "  } else {\n",
       "    load_libs(js_urls, function() {\n",
       "      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
       "      run_inline_js();\n",
       "    });\n",
       "  }\n",
       "}(window));"
      ],
      "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n\n  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n    root._bokeh_onload_callbacks = [];\n    root._bokeh_is_loading = undefined;\n  }\n\n  \n\n  \n  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  var NB_LOAD_WARNING = {'data': {'text/html':\n     \"<div style='background-color: #fdd'>\\n\"+\n     \"<p>\\n\"+\n     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n     \"</p>\\n\"+\n     \"<ul>\\n\"+\n     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n     \"</ul>\\n\"+\n     \"<code>\\n\"+\n     \"from bokeh.resources import INLINE\\n\"+\n     \"output_notebook(resources=INLINE)\\n\"+\n     \"</code>\\n\"+\n     \"</div>\"}};\n\n  function display_loaded() {\n    var el = document.getElementById(\"2776\");\n    if (el != null) {\n      el.textContent = \"BokehJS is loading...\";\n    }\n    if (root.Bokeh !== undefined) {\n      if (el != null) {\n        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(display_loaded, 100)\n    }\n  }\n\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n    }\n    finally {\n      delete root._bokeh_onload_callbacks\n    }\n    console.info(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(js_urls, callback) {\n    root._bokeh_onload_callbacks.push(callback);\n    if (root._bokeh_is_loading > 0) {\n      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls == null || js_urls.length === 0) {\n      run_callbacks();\n      return null;\n    }\n    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    root._bokeh_is_loading = js_urls.length;\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      var s = document.createElement('script');\n      s.src = url;\n      s.async = false;\n      s.onreadystatechange = s.onload = function() {\n        root._bokeh_is_loading--;\n        if (root._bokeh_is_loading === 0) {\n          console.log(\"Bokeh: all BokehJS libraries loaded\");\n          run_callbacks()\n        }\n      };\n      s.onerror = function() {\n        console.warn(\"failed to load library \" + url);\n      };\n      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.getElementsByTagName(\"head\")[0].appendChild(s);\n    }\n  };var element = document.getElementById(\"2776\");\n  if (element == null) {\n    console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2776' but no matching script tag was found. \")\n    return false;\n  }\n\n  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.1.min.js\"];\n\n  var inline_js = [\n    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    \n    function(Bokeh) {\n      \n    },\n    function(Bokeh) {\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.1.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.1.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.1.min.css\");\n    }\n  ];\n\n  function run_inline_js() {\n    \n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }if (force === true) {\n        display_loaded();\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    } else if (force !== true) {\n      var cell = $(document.getElementById(\"2776\")).parents('.cell').data().cell;\n      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n    }\n\n  }\n\n  if (root._bokeh_is_loading === 0) {\n    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n    run_inline_js();\n  } else {\n    load_libs(js_urls, function() {\n      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n      run_inline_js();\n    });\n  }\n}(window));"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from ipywidgets import interact\n",
    "import numpy as np\n",
    "\n",
    "from bokeh.io import push_notebook, show, output_notebook\n",
    "from bokeh.plotting import figure\n",
    "output_notebook()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.linspace(0, 2*np.pi, 2000)\n",
    "y = np.sin(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = figure(title=\"simple line example\", plot_height=300, plot_width=600, y_range=(-5,5))\n",
    "r = p.line(x, y, color=\"#2222aa\", line_width=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def update(f, w=1, A=1, phi=0):\n",
    "    if   f == \"sin\": func = np.sin\n",
    "    elif f == \"cos\": func = np.cos\n",
    "    elif f == \"tan\": func = np.tan\n",
    "    r.data_source.data['y'] = A * func(w * x + phi)\n",
    "    push_notebook()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "  <div class=\"bk-root\" id=\"ca29a166-b784-45de-9bc8-b8c1c571f1c0\"></div>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "(function(root) {\n",
       "  function embed_document(root) {\n",
       "    \n",
       "  var docs_json = {\"4a2f3c4d-cd38-442e-a39a-83af0e1eee61\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"2788\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"2793\",\"type\":\"LinearAxis\"}],\"plot_height\":300,\"renderers\":[{\"id\":\"2788\",\"type\":\"LinearAxis\"},{\"id\":\"2792\",\"type\":\"Grid\"},{\"id\":\"2793\",\"type\":\"LinearAxis\"},{\"id\":\"2797\",\"type\":\"Grid\"},{\"id\":\"2806\",\"type\":\"BoxAnnotation\"},{\"id\":\"2816\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"2777\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"2804\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"2780\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"2784\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"2782\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"2786\",\"type\":\"LinearScale\"}},\"id\":\"2778\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"2786\",\"type\":\"LinearScale\"},{\"attributes\":{\"formatter\":{\"id\":\"2820\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"2778\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"2794\",\"type\":\"BasicTicker\"}},\"id\":\"2793\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"2824\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null},\"id\":\"2780\",\"type\":\"DataRange1d\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2815\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"2798\",\"type\":\"PanTool\"},{\"attributes\":{\"source\":{\"id\":\"2813\",\"type\":\"ColumnDataSource\"}},\"id\":\"2817\",\"type\":\"CDSView\"},{\"attributes\":{\"line_color\":\"#2222aa\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2814\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[2000]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[2000]}},\"selected\":{\"id\":\"2824\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2825\",\"type\":\"UnionRenderers\"}},\"id\":\"2813\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"2794\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"2822\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"data_source\":{\"id\":\"2813\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2814\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2815\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"2817\",\"type\":\"CDSView\"}},\"id\":\"2816\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2799\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"overlay\":{\"id\":\"2806\",\"type\":\"BoxAnnotation\"}},\"id\":\"2800\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"plot\":{\"id\":\"2778\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"2789\",\"type\":\"BasicTicker\"}},\"id\":\"2792\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"2802\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"2803\",\"type\":\"HelpTool\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"2798\",\"type\":\"PanTool\"},{\"id\":\"2799\",\"type\":\"WheelZoomTool\"},{\"id\":\"2800\",\"type\":\"BoxZoomTool\"},{\"id\":\"2801\",\"type\":\"SaveTool\"},{\"id\":\"2802\",\"type\":\"ResetTool\"},{\"id\":\"2803\",\"type\":\"HelpTool\"}]},\"id\":\"2804\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"2801\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"2820\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"plot\":null,\"text\":\"simple line example\"},\"id\":\"2777\",\"type\":\"Title\"},{\"attributes\":{\"formatter\":{\"id\":\"2822\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"2778\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"2789\",\"type\":\"BasicTicker\"}},\"id\":\"2788\",\"type\":\"LinearAxis\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"2806\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"2825\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2784\",\"type\":\"LinearScale\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"2778\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"2794\",\"type\":\"BasicTicker\"}},\"id\":\"2797\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"2789\",\"type\":\"BasicTicker\"},{\"attributes\":{\"callback\":null,\"end\":5,\"start\":-5},\"id\":\"2782\",\"type\":\"Range1d\"}],\"root_ids\":[\"2778\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.1\"}};\n",
       "  var render_items = [{\"docid\":\"4a2f3c4d-cd38-442e-a39a-83af0e1eee61\",\"notebook_comms_target\":\"2826\",\"roots\":{\"2778\":\"ca29a166-b784-45de-9bc8-b8c1c571f1c0\"}}];\n",
       "  root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "\n",
       "  }\n",
       "  if (root.Bokeh !== undefined) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (root.Bokeh !== undefined) {\n",
       "        embed_document(root);\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "      attempts++;\n",
       "      if (attempts > 100) {\n",
       "        console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "    }, 10, root)\n",
       "  }\n",
       "})(window);"
      ],
      "application/vnd.bokehjs_exec.v0+json": ""
     },
     "metadata": {
      "application/vnd.bokehjs_exec.v0+json": {
       "id": "2778"
      }
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<p><code>&lt;Bokeh Notebook handle for <strong>In[20]</strong>&gt;</code></p>"
      ],
      "text/plain": [
       "<bokeh.io.notebook.CommsHandle at 0x1189158d0>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(p, notebook_handle=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d37da8dea94d4885bd900835eee394fe",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(Dropdown(description='f', options=('sin', 'cos', 'tan'), value='sin'), IntSlider(value=1…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<function __main__.update(f, w=1, A=1, phi=0)>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "interact(update, f=[\"sin\", \"cos\", \"tan\"], w=(0,100), A=(1,5), phi=(0, 20, 0.1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What this is supposed to look like! https://bokeh.pydata.org/en/latest/docs/user_guide/notebook.html#jupyter-interactors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "<a id=\"panels\"></a>\n",
    "\n",
    "## Addendum: Pandas Panels\n",
    "\n",
    "Panel is a container for 3-dimensional data. The term panel data is derived from econometrics and is partially responsible for the name pandas: pan(el)-da(ta)-s. The names for the 3 axes give some semantic meaning to describing operations involving panel data and, in particular, econometric analysis of panel data:\n",
    "\n",
    "* **items** -- axis 0, each item corresponds to a DataFrame contained inside\n",
    "* **major_axis** -- axis 1, it is the index (rows) of each of the DataFrames\n",
    "* **minor_axis** -- axis 2, it is the columns of each of the DataFrames"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### From 3D ndarray with optional axis labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.random.randn(2, 5, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 5, 4)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0.79952443, -0.00936052,  0.70187707, -0.8051021 ],\n",
       "        [-1.34998935,  0.34724837,  1.24084546, -1.21199055],\n",
       "        [ 0.29065191,  0.69633502, -0.2621058 ,  0.39778763],\n",
       "        [-0.22792923,  0.56419148,  0.82612156, -0.59250644],\n",
       "        [ 1.76917788, -0.75050696, -0.75820827,  0.10765544]],\n",
       "\n",
       "       [[-1.95786387,  0.05917021, -1.35622965,  0.64239166],\n",
       "        [-0.14881912, -0.34577694,  1.01191879,  3.21601805],\n",
       "        [-0.10897603, -0.00656925, -0.91619736,  0.66604984],\n",
       "        [-2.10729674, -1.62688628,  1.59563076, -1.74531544],\n",
       "        [-0.25511612, -0.3995454 , -0.17433442, -0.14925264]]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/luke/miniconda3/envs/python3/lib/python3.7/site-packages/IPython/core/interactiveshell.py:3267: FutureWarning: \n",
      "Panel is deprecated and will be removed in a future version.\n",
      "The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method\n",
      "Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.\n",
      "Pandas provides a `.to_xarray()` method to help automate this conversion.\n",
      "\n",
      "  exec(code_obj, self.user_global_ns, self.user_ns)\n"
     ]
    }
   ],
   "source": [
    "panel1 = pd.Panel(data, items=['Item1', 'Item2'],\n",
    "    major_axis=pd.date_range('2/25/1852', periods=data.shape[1]),\n",
    "    minor_axis=['A', 'B', 'C', 'D'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<class 'pandas.core.panel.Panel'>\n",
       "Dimensions: 2 (items) x 5 (major_axis) x 4 (minor_axis)\n",
       "Items axis: Item1 to Item2\n",
       "Major_axis axis: 1852-02-25 00:00:00 to 1852-02-29 00:00:00\n",
       "Minor_axis axis: A to D"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1852-02-25</th>\n",
       "      <td>0.799524</td>\n",
       "      <td>-0.009361</td>\n",
       "      <td>0.701877</td>\n",
       "      <td>-0.805102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-26</th>\n",
       "      <td>-1.349989</td>\n",
       "      <td>0.347248</td>\n",
       "      <td>1.240845</td>\n",
       "      <td>-1.211991</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-27</th>\n",
       "      <td>0.290652</td>\n",
       "      <td>0.696335</td>\n",
       "      <td>-0.262106</td>\n",
       "      <td>0.397788</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-28</th>\n",
       "      <td>-0.227929</td>\n",
       "      <td>0.564191</td>\n",
       "      <td>0.826122</td>\n",
       "      <td>-0.592506</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-29</th>\n",
       "      <td>1.769178</td>\n",
       "      <td>-0.750507</td>\n",
       "      <td>-0.758208</td>\n",
       "      <td>0.107655</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   A         B         C         D\n",
       "1852-02-25  0.799524 -0.009361  0.701877 -0.805102\n",
       "1852-02-26 -1.349989  0.347248  1.240845 -1.211991\n",
       "1852-02-27  0.290652  0.696335 -0.262106  0.397788\n",
       "1852-02-28 -0.227929  0.564191  0.826122 -0.592506\n",
       "1852-02-29  1.769178 -0.750507 -0.758208  0.107655"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.Item1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1852-02-25</th>\n",
       "      <td>-1.957864</td>\n",
       "      <td>0.059170</td>\n",
       "      <td>-1.356230</td>\n",
       "      <td>0.642392</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-26</th>\n",
       "      <td>-0.148819</td>\n",
       "      <td>-0.345777</td>\n",
       "      <td>1.011919</td>\n",
       "      <td>3.216018</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-27</th>\n",
       "      <td>-0.108976</td>\n",
       "      <td>-0.006569</td>\n",
       "      <td>-0.916197</td>\n",
       "      <td>0.666050</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-28</th>\n",
       "      <td>-2.107297</td>\n",
       "      <td>-1.626886</td>\n",
       "      <td>1.595631</td>\n",
       "      <td>-1.745315</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-29</th>\n",
       "      <td>-0.255116</td>\n",
       "      <td>-0.399545</td>\n",
       "      <td>-0.174334</td>\n",
       "      <td>-0.149253</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   A         B         C         D\n",
       "1852-02-25 -1.957864  0.059170 -1.356230  0.642392\n",
       "1852-02-26 -0.148819 -0.345777  1.011919  3.216018\n",
       "1852-02-27 -0.108976 -0.006569 -0.916197  0.666050\n",
       "1852-02-28 -2.107297 -1.626886  1.595631 -1.745315\n",
       "1852-02-29 -0.255116 -0.399545 -0.174334 -0.149253"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.Item2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Item1</th>\n",
       "      <th>Item2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>major</th>\n",
       "      <th>minor</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">1852-02-25</th>\n",
       "      <th>A</th>\n",
       "      <td>0.799524</td>\n",
       "      <td>-1.957864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>-0.009361</td>\n",
       "      <td>0.059170</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>0.701877</td>\n",
       "      <td>-1.356230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>-0.805102</td>\n",
       "      <td>0.642392</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">1852-02-26</th>\n",
       "      <th>A</th>\n",
       "      <td>-1.349989</td>\n",
       "      <td>-0.148819</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>0.347248</td>\n",
       "      <td>-0.345777</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>1.240845</td>\n",
       "      <td>1.011919</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>-1.211991</td>\n",
       "      <td>3.216018</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">1852-02-27</th>\n",
       "      <th>A</th>\n",
       "      <td>0.290652</td>\n",
       "      <td>-0.108976</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>0.696335</td>\n",
       "      <td>-0.006569</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>-0.262106</td>\n",
       "      <td>-0.916197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>0.397788</td>\n",
       "      <td>0.666050</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">1852-02-28</th>\n",
       "      <th>A</th>\n",
       "      <td>-0.227929</td>\n",
       "      <td>-2.107297</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>0.564191</td>\n",
       "      <td>-1.626886</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>0.826122</td>\n",
       "      <td>1.595631</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>-0.592506</td>\n",
       "      <td>-1.745315</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">1852-02-29</th>\n",
       "      <th>A</th>\n",
       "      <td>1.769178</td>\n",
       "      <td>-0.255116</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>-0.750507</td>\n",
       "      <td>-0.399545</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>-0.758208</td>\n",
       "      <td>-0.174334</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>0.107655</td>\n",
       "      <td>-0.149253</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                     Item1     Item2\n",
       "major      minor                    \n",
       "1852-02-25 A      0.799524 -1.957864\n",
       "           B     -0.009361  0.059170\n",
       "           C      0.701877 -1.356230\n",
       "           D     -0.805102  0.642392\n",
       "1852-02-26 A     -1.349989 -0.148819\n",
       "           B      0.347248 -0.345777\n",
       "           C      1.240845  1.011919\n",
       "           D     -1.211991  3.216018\n",
       "1852-02-27 A      0.290652 -0.108976\n",
       "           B      0.696335 -0.006569\n",
       "           C     -0.262106 -0.916197\n",
       "           D      0.397788  0.666050\n",
       "1852-02-28 A     -0.227929 -2.107297\n",
       "           B      0.564191 -1.626886\n",
       "           C      0.826122  1.595631\n",
       "           D     -0.592506 -1.745315\n",
       "1852-02-29 A      1.769178 -0.255116\n",
       "           B     -0.750507 -0.399545\n",
       "           C     -0.758208 -0.174334\n",
       "           D      0.107655 -0.149253"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.to_frame()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### From dict of DataFrame objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)),\n",
    "        'Item2' : pd.DataFrame(np.random.randn(4, 2))}\n",
    "panel2 = pd.Panel(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.138891</td>\n",
       "      <td>-0.131624</td>\n",
       "      <td>1.141014</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.332791</td>\n",
       "      <td>0.710962</td>\n",
       "      <td>0.645042</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.203529</td>\n",
       "      <td>-0.008017</td>\n",
       "      <td>-0.072306</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-1.095019</td>\n",
       "      <td>-1.327951</td>\n",
       "      <td>-0.031243</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0         1         2\n",
       "0 -0.138891 -0.131624  1.141014\n",
       "1 -0.332791  0.710962  0.645042\n",
       "2  0.203529 -0.008017 -0.072306\n",
       "3 -1.095019 -1.327951 -0.031243"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel2.Item1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.575256</td>\n",
       "      <td>0.020160</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.169333</td>\n",
       "      <td>0.599117</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.533060</td>\n",
       "      <td>-1.688195</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1.144176</td>\n",
       "      <td>-0.199781</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0         1   2\n",
       "0 -0.575256  0.020160 NaN\n",
       "1 -1.169333  0.599117 NaN\n",
       "2  1.533060 -1.688195 NaN\n",
       "3  1.144176 -0.199781 NaN"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel2.Item2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Item1</th>\n",
       "      <th>Item2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>major</th>\n",
       "      <th>minor</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.138891</td>\n",
       "      <td>-0.575256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.131624</td>\n",
       "      <td>0.020160</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.332791</td>\n",
       "      <td>-1.169333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.710962</td>\n",
       "      <td>0.599117</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>0</th>\n",
       "      <td>0.203529</td>\n",
       "      <td>1.533060</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.008017</td>\n",
       "      <td>-1.688195</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>0</th>\n",
       "      <td>-1.095019</td>\n",
       "      <td>1.144176</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.327951</td>\n",
       "      <td>-0.199781</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                Item1     Item2\n",
       "major minor                    \n",
       "0     0     -0.138891 -0.575256\n",
       "      1     -0.131624  0.020160\n",
       "1     0     -0.332791 -1.169333\n",
       "      1      0.710962  0.599117\n",
       "2     0      0.203529  1.533060\n",
       "      1     -0.008017 -1.688195\n",
       "3     0     -1.095019  1.144176\n",
       "      1     -1.327951 -0.199781"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel2.to_frame()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Indexing and selection\n",
    "\n",
    "Operation                     | Syntax             | Result\n",
    "------------------------------|--------------------|----------\n",
    "Select item                   | `wp[item]`         | DataFrame\n",
    "Get slice at major_axis label | `wp.major_xs(val)` | DataFrame\n",
    "Get slice at minor_axis label | `wp.minor_xs(val)` | DataFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1852-02-25</th>\n",
       "      <td>0.799524</td>\n",
       "      <td>-0.009361</td>\n",
       "      <td>0.701877</td>\n",
       "      <td>-0.805102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-26</th>\n",
       "      <td>-1.349989</td>\n",
       "      <td>0.347248</td>\n",
       "      <td>1.240845</td>\n",
       "      <td>-1.211991</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-27</th>\n",
       "      <td>0.290652</td>\n",
       "      <td>0.696335</td>\n",
       "      <td>-0.262106</td>\n",
       "      <td>0.397788</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-28</th>\n",
       "      <td>-0.227929</td>\n",
       "      <td>0.564191</td>\n",
       "      <td>0.826122</td>\n",
       "      <td>-0.592506</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-29</th>\n",
       "      <td>1.769178</td>\n",
       "      <td>-0.750507</td>\n",
       "      <td>-0.758208</td>\n",
       "      <td>0.107655</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   A         B         C         D\n",
       "1852-02-25  0.799524 -0.009361  0.701877 -0.805102\n",
       "1852-02-26 -1.349989  0.347248  1.240845 -1.211991\n",
       "1852-02-27  0.290652  0.696335 -0.262106  0.397788\n",
       "1852-02-28 -0.227929  0.564191  0.826122 -0.592506\n",
       "1852-02-29  1.769178 -0.750507 -0.758208  0.107655"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1['Item1']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['1852-02-25', '1852-02-26', '1852-02-27', '1852-02-28',\n",
       "               '1852-02-29'],\n",
       "              dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.major_axis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Item1</th>\n",
       "      <th>Item2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <td>0.799524</td>\n",
       "      <td>-1.957864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>-0.009361</td>\n",
       "      <td>0.059170</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>0.701877</td>\n",
       "      <td>-1.356230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>-0.805102</td>\n",
       "      <td>0.642392</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      Item1     Item2\n",
       "A  0.799524 -1.957864\n",
       "B -0.009361  0.059170\n",
       "C  0.701877 -1.356230\n",
       "D -0.805102  0.642392"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.major_xs('1852-02-25')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Item1</th>\n",
       "      <th>Item2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <td>0.290652</td>\n",
       "      <td>-0.108976</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>0.696335</td>\n",
       "      <td>-0.006569</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>-0.262106</td>\n",
       "      <td>-0.916197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>0.397788</td>\n",
       "      <td>0.666050</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      Item1     Item2\n",
       "A  0.290652 -0.108976\n",
       "B  0.696335 -0.006569\n",
       "C -0.262106 -0.916197\n",
       "D  0.397788  0.666050"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.major_xs(panel1.major_axis[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['A', 'B', 'C', 'D'], dtype='object')"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.minor_axis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Item1</th>\n",
       "      <th>Item2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1852-02-25</th>\n",
       "      <td>0.701877</td>\n",
       "      <td>-1.356230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-26</th>\n",
       "      <td>1.240845</td>\n",
       "      <td>1.011919</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-27</th>\n",
       "      <td>-0.262106</td>\n",
       "      <td>-0.916197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-28</th>\n",
       "      <td>0.826122</td>\n",
       "      <td>1.595631</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-29</th>\n",
       "      <td>-0.758208</td>\n",
       "      <td>-0.174334</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               Item1     Item2\n",
       "1852-02-25  0.701877 -1.356230\n",
       "1852-02-26  1.240845  1.011919\n",
       "1852-02-27 -0.262106 -0.916197\n",
       "1852-02-28  0.826122  1.595631\n",
       "1852-02-29 -0.758208 -0.174334"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1.minor_xs('C')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Item operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "panel1['Item3'] = panel1['Item1']/panel1['Item2']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>D</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1852-02-25</th>\n",
       "      <td>-0.408366</td>\n",
       "      <td>-0.158197</td>\n",
       "      <td>-0.517521</td>\n",
       "      <td>-1.253289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-26</th>\n",
       "      <td>9.071344</td>\n",
       "      <td>-1.004255</td>\n",
       "      <td>1.226230</td>\n",
       "      <td>-0.376861</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-27</th>\n",
       "      <td>-2.667118</td>\n",
       "      <td>-105.999233</td>\n",
       "      <td>0.286080</td>\n",
       "      <td>0.597234</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-28</th>\n",
       "      <td>0.108162</td>\n",
       "      <td>-0.346792</td>\n",
       "      <td>0.517740</td>\n",
       "      <td>0.339484</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1852-02-29</th>\n",
       "      <td>-6.934795</td>\n",
       "      <td>1.878402</td>\n",
       "      <td>4.349160</td>\n",
       "      <td>-0.721297</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   A           B         C         D\n",
       "1852-02-25 -0.408366   -0.158197 -0.517521 -1.253289\n",
       "1852-02-26  9.071344   -1.004255  1.226230 -0.376861\n",
       "1852-02-27 -2.667118 -105.999233  0.286080  0.597234\n",
       "1852-02-28  0.108162   -0.346792  0.517740  0.339484\n",
       "1852-02-29 -6.934795    1.878402  4.349160 -0.721297"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "panel1['Item3']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Alternative to Panels: Create DataFrame with MultiIndex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>item1</th>\n",
       "      <th>item2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">a</th>\n",
       "      <th>1</th>\n",
       "      <td>0.498497</td>\n",
       "      <td>0.408550</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.693409</td>\n",
       "      <td>0.476624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">b</th>\n",
       "      <th>1</th>\n",
       "      <td>0.020663</td>\n",
       "      <td>0.378357</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.506982</td>\n",
       "      <td>0.809369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        item1     item2\n",
       "a 1  0.498497  0.408550\n",
       "  2  0.693409  0.476624\n",
       "b 1  0.020663  0.378357\n",
       "  2  0.506982  0.809369"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame(np.random.rand(4, 2),\n",
    "                  index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],\n",
    "                  columns=['item1', 'item2'])\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a  1    0.498497\n",
       "   2    0.693409\n",
       "b  1    0.020663\n",
       "   2    0.506982\n",
       "Name: item1, dtype: float64"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['item1']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>item1</th>\n",
       "      <th>item2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.498497</td>\n",
       "      <td>0.408550</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.693409</td>\n",
       "      <td>0.476624</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      item1     item2\n",
       "1  0.498497  0.408550\n",
       "2  0.693409  0.476624"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.loc['a']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "See additional documentation at <http://pandas.pydata.org/pandas-docs/stable/dsintro.html#panel>."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
